package tcm.com.gistone.api.restController;

import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import tcm.com.gistone.api.service.WordService;
import tcm.com.gistone.database.config.GetBySqlMapper;
import tcm.com.gistone.database.entity.Word;
import tcm.com.gistone.util.ClientUtil;
import tcm.com.gistone.util.Combination;
import tcm.com.gistone.util.EdatResult;
import tcm.com.gistone.util.Math;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by wangfan on 2017/8/12.
 */
@RestController("apiAnalysisController")
@RequestMapping("api/analysis")
public class AnalysisController {

    @Autowired
    private WordService wordService;
    @Autowired
    private GetBySqlMapper getBySqlMapper;


    @RequestMapping(value = "getAnalysis", method = RequestMethod.POST)
    public EdatResult getAnalysis(HttpServletRequest request, HttpServletResponse response) {
        try {

            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            Integer specialId = null;
            String confidenceTable ="tb_confidence_copy";
            if (data.has("specialId")) {
                specialId = data.getInt("specialId");
                confidenceTable =confidenceTable+specialId;
            }
          
            double confidence = data.getDouble("confidence");
            int support = data.getInt("support");
            String word = data.getString("word");
            System.out.println(word);
            String sectype = data.getString("sectype");

            Map map =new HashMap();
            long queryWordId = wordService.getWordIdByWordString(specialId, word);

            System.out.println(queryWordId);
            map .put("wordId",queryWordId);
            Map theme =wordService.getWordTheme(queryWordId,specialId);
            map .put("wordThemeName",theme.get("theme_name"));
            map .put("wordThemeId",theme.get("theme_id"));

            String sql;

            if (null == sectype || sectype.isEmpty()) {
                sql =
                        "SELECT  * from (SELECT count(distinct b.ano_word_id) as no,b.ano_word_type as type,(select theme_name from tb_theme where theme_id =type ) as name,(select special_id from tb_theme where theme_id =type ) as special_id " +
                                "FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id " +
                                "and a.value>=" + confidence + " and b.num >=" + support + "   where a.word_id = " + queryWordId + " group by b.ano_word_type " +
                                "union " +
                                "SELECT count(distinct b.word_id) as no,b.word_type as type,(select theme_name from tb_theme where theme_id =type ) as name ,(select special_id from tb_theme where theme_id =type ) as special_id " +
                                "FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id " +
                                "and a.value>=" + confidence + " and b.num >=" + support + "   where a.ano_word_id = " + queryWordId + " group by b.word_type ) d " ;

                    if(null!=specialId){
                       sql =sql+" WHERE special_id =" +specialId;
                    }
                sql =sql+   " order by no DESC;";
            } else {

                sql =
                        "SELECT  * from (SELECT count(distinct b.ano_word_id) as no,b.ano_word_type as type,(select theme_name from tb_theme where theme_id =type ) as name,(select special_id from tb_theme where theme_id =type ) as special_id  " +
                                "FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id " +
                                "and a.value>=" + confidence + " and b.num >=" + support + " AND b.sec_type ='" + sectype + "' where a.word_id = " + queryWordId + " group by b.ano_word_type " +
                                " union " +
                                "SELECT count(distinct b.word_id) as no,b.word_type as type,(select theme_name from tb_theme where theme_id =type ) as name ,(select special_id from tb_theme where theme_id =type ) as special_id  " +
                                "FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id  " +
                                "and a.value>=" + confidence + " and b.num >=" + support + " AND b.sec_type ='" + sectype + "' where a.ano_word_id = " + queryWordId + " group by b.word_type ) d " ;
                if(null!=specialId){
                    sql =sql+" WHERE special_id =1";
                }
                sql =sql+   " order by no DESC;";
            }
            List<Map> result = getBySqlMapper.findRecords(sql);


            map .put("result",result);
            return EdatResult.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "发生错误");
        }
    }


    @RequestMapping(value = "getTwoAnalysis", method = RequestMethod.POST)
    public EdatResult getTwoAnalysis(HttpServletRequest request, HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            Integer specialId = null;
            String confidenceTable ="tb_confidence_copy";
            if (data.has("specialId")) {
                specialId = data.getInt("specialId");
                confidenceTable =confidenceTable+specialId;
            }
            double confidence = data.getDouble("confidence");
            int support = data.getInt("support");
            String word = data.getString("word");
            String sectype = data.getString("sectype");
            String [] arr =word.split(" ");
            Map map =new HashMap();
            long wordId = wordService.getWordIdByWordString(specialId, arr[0]);
            long wordTypeId = wordService.getWordTypeByID(wordId);
            String type1 =wordService.getWordThemeById(wordTypeId);

            long anoWordId = wordService.getWordIdByWordString(specialId, arr[1]);
            long typeId = wordService.getWordTypeByID(anoWordId);
            String type2 =wordService.getWordThemeById(typeId);



            map .put("type1",type1);
            map .put("type2",type2);

            String sql;

            if (typeId >wordTypeId) {
                sql = "SELECT b.book_id as bookId ,(select book_name from tb_bookinfo where  status=7 and book_id =bookId ) as bookName, " +
                        " sum(b.num) as no,b.ano_word_id as wordId ,a.value as confidence, " +
                        " (select word from tb_word where word_id =wordId ) as name" +
                        " FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id " +
                        " and a.ano_word_id = b.ano_word_id " +
                        " and a.value>=" + confidence + "  and b.num >=" + support + " ";


                if (null != sectype && !sectype.isEmpty()) {
                    sql = sql+ "AND b.sec_type ='" + sectype + "' ";
                }
                sql =sql+
                        " where a.word_id = " + wordId + " and b.ano_word_id ="+anoWordId +
                        " group by b.book_id,a.value" +
                        " order by no desc ";

            } else {

                sql = "SELECT b.book_id as bookId ,(select book_name from tb_bookinfo where status=7 and book_id =bookId ) as bookName, " +
                        " sum(b.num) as no,b.word_id as wordId , a.value as confidence, " +
                        " (select word from tb_word where word_id =wordId ) as name" +
                        " FROM  tb_words_relation_copy b left join "+confidenceTable+" a " +
                        " on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id" +
                        " and a.value>=" + confidence + "  and b.num >=" + support;



                if (null != sectype &&!sectype.isEmpty()) {
                    sql = sql+" AND b.sec_type ='" + sectype + "' ";

                }

                sql =sql+
                        " where a.ano_word_id =  " + wordId + " and b.word_id ="+anoWordId +
                        " group by b.book_id,a.value" +
                        " order by no desc ";

            }
            List<Map> result = getBySqlMapper.findRecords(sql);


            map .put("result",result);
            return EdatResult.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "fail");
        }
    }



    /* 词频柱状图*/
    @RequestMapping(value = "getRelation", method = RequestMethod.POST)
    public EdatResult getRelation(HttpServletRequest request, HttpServletResponse response) {
        try {

            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            Integer typeId = data.getInt("typeId");
            Integer specialId = null;
            if (data.has("specialId")) {
                specialId = data.getInt("specialId");
            }
            double confidence = data.getDouble("confidence");
            int support = data.getInt("support");
            String word = data.getString("word");
            String sectype = data.getString("sectype");
            Long wordId =wordService.getWordIdByWordString(specialId, word);
            System.out.println(wordId);
            Long wordTypeId = wordService.getWordTypeByID(wordId);
                    String sql;
            sql = getSql(typeId, confidence, support, sectype, wordId, wordTypeId,specialId);
            List<Map> result = getBySqlMapper.findRecords(sql);
            return EdatResult.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "fail");
        }
    }

    @RequestMapping(value = "getThreeRelation", method = RequestMethod.POST)
    public EdatResult getThreeRelation(HttpServletRequest request, HttpServletResponse response) {
        try {

            ClientUtil.SetCharsetAndHeader(request, response);
            JSONObject data = JSONObject.fromObject(request.getParameter("data"));
            Integer typeId = data.getInt("typeId");
            Integer specialId = null;
            if (data.has("specialId")) {
                specialId = data.getInt("specialId");

            }
            double confidence = data.getDouble("confidence");
            int support = data.getInt("support");
            String word = data.getString("word");
            String sectype = data.getString("sectype");
            Long wordId =wordService.getWordIdByWordString(specialId, word);
            long wordNum =wordService.getNumberByWordId(specialId,wordId);
            Long wordTypeId = wordService.getWordTypeByID(wordId);
            String sql;
            sql = getSql(typeId, confidence, support, sectype, wordId, wordTypeId,specialId);
            List<Map> twoResult = getBySqlMapper.findRecords(sql);

            List<Map> result =new ArrayList<>() ;
            int n=2;
            if(twoResult.size()<2){
                return EdatResult.build(1, "结果记录少于两条，不能进行深度分析");
            }else if(twoResult.size()==2){

                Map m =getMap(specialId, word, wordId, wordNum, twoResult,0,1);
                result.add(m);

            }else if(twoResult.size()>3){

                int size =twoResult.size();

                if(size>5){
                    size=5;

                }

                String[] datas =new String[size];

                for (int i = 0; i < size; i++) {
//                    int nu =1;
                    datas[i]=i+"";
                }
                System.out.println(datas.toString());
                List<String> stringList =new ArrayList<>();
                Math.combinationSelect(datas, 0,new String[n] ,0,stringList);
                System.out.println("--------");
                for (String s : stringList) {
                    String[] arr=s.split(" ");
                    System.out.println(s);
                    Map m =getMap(specialId, word, wordId, wordNum, twoResult,Integer.valueOf(arr[0]),Integer.valueOf(arr[1]));
                    result.add(m);

                }

            }



            Collections.sort(result, new Comparator(){
                @Override
                public int compare(Object o1, Object o2) {
                   Map m1=(Map)o1;
                   Map m2=(Map)o2;
                   return Float.compare(Float.valueOf(m2.get("confidence").toString()),Float.valueOf(m1.get("confidence").toString()));
                }
            });
            return EdatResult.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return EdatResult.build(1, "fail");
        }
    }

    private Map getMap(Integer specialId, String word, Long wordId, long wordNum, List<Map> twoResult,int num1,int num2) {
        String name1 = twoResult.get(num1).get("name").toString();
        long id1 = wordService.getWordIdByWordString(specialId,name1);
        String name2 = twoResult.get(num2).get("name").toString();
        long id2 = wordService.getWordIdByWordString(specialId,name2);
        int number  =wordService.getNumberByThreeWord(specialId,wordId,id1,id2);
        Map m =new HashMap();
        m.put("word1",word);
        m.put("word2",name1);
        m.put("word3",name2);
        m.put("number",number);
        DecimalFormat df = new DecimalFormat("0.00");
        System.out.println("number-"+number+" : "+wordNum);
        System.out.println(number/wordNum);
        System.out.println(df.format((float)number/wordNum));
        m.put("confidence", df.format((float)number/wordNum));
        return  m;
    }

    /*分页table，针对单个词查询关联*/
    @RequestMapping(value = "pageTable2", method = RequestMethod.POST)
    public Map pageTable2(HttpServletRequest request,
                          HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            int pageNumber = Integer.parseInt(request
                    .getParameter("pageNumber"));
            int pageSize = Integer.parseInt(request
                    .getParameter("pageSize"));

            Integer specialId = null;
            String confidenceTable ="tb_confidence_copy";
            if (null!=request.getParameter("specialId")&&!request.getParameter("specialId").isEmpty()) {
                 specialId = Integer.parseInt(request.getParameter("specialId"));

                confidenceTable =confidenceTable+specialId;
            }
           
            double confidence = Double.parseDouble(request.getParameter("confidence"));
            int support = Integer.parseInt(request.getParameter("support"));
            String word = request.getParameter("word");
            String sectype = request.getParameter("sectype");

            String [] arr =word.split(" ");
            long wordId = wordService.getWordIdByWordString(specialId, arr[0]);
            long wordTypeId = wordService.getWordTypeByID(wordId);

            long anoWordId = wordService.getWordIdByWordString(specialId, arr[1]);
            long typeId = wordService.getWordTypeByID(anoWordId);


            String sql;
            String countSql;


           if (typeId >wordTypeId) {
                sql = "SELECT (select word from tb_word where word_id =58658 ) as wordName, " +
                        " sum(b.num) as no,b.ano_word_id as wordId ,a.value as confidence, " +
                        " (select word from tb_word where word_id =wordId ) as name" +
                        " FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id " +
                        " and a.ano_word_id = b.ano_word_id " +
                        " and a.value>=" + confidence + "  and b.num >=" + support + " ";


                if (null != sectype && !sectype.isEmpty()) {
                    sql = sql+ "AND b.sec_type ='" + sectype + "' ";
                }
                sql =sql+
                        " where a.word_id = " + wordId + " and b.ano_word_id ="+anoWordId +
                        " group by b.ano_word_id,a.value" +
                        " order by no desc ";

            } else {

                sql = "SELECT (select word from tb_word where word_id =58658 ) as wordName, " +
                        " sum(b.num) as no,b.word_id as wordId , a.value as confidence, " +
                        " (select word from tb_word where word_id =wordId ) as name" +
                        " FROM  tb_words_relation_copy b left join "+confidenceTable+" a " +
                        " on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id" +
                        " and a.value>=" + confidence + "  and b.num >=" + support;



                if (null != sectype &&!sectype.isEmpty()) {
                    sql = sql+" AND b.sec_type ='" + sectype + "' ";

                }

                sql =sql+
                        " where a.ano_word_id =  " + wordId + " and b.word_id ="+anoWordId +
                        " group by b.word_id,a.value" +
                        " order by no desc ";

            }



            countSql ="select count(*) from ("+sql+")temp";



            sql =sql+" limit " + pageNumber + "," + pageSize;

            List<Map> result = getBySqlMapper.findRecords(sql);
            if(result.size()<1){
                return null;
            }
            int total = getBySqlMapper.findrows(countSql);
            Map map = new HashMap();
            map.put("total", total);
            map.put("rows", result);
            map.put("page", pageNumber / pageSize);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    @RequestMapping(value = "pageTable", method = RequestMethod.POST)
    public Map pageTable(HttpServletRequest request,
                         HttpServletResponse response) {
        try {
            ClientUtil.SetCharsetAndHeader(request, response);
            int pageNumber = Integer.parseInt(request
                    .getParameter("pageNumber"));
            int pageSize = Integer.parseInt(request
                    .getParameter("pageSize"));
            Integer typeId = Integer.parseInt(request
                    .getParameter("typeId"));

            Integer specialId = null;
       
            if (null!=request.getParameter("specialId")&&!request.getParameter("specialId").isEmpty()) {
                specialId = Integer.parseInt(request.getParameter("specialId"));

           
            }
            System.out.println("specialId-----"+specialId);
            double confidence = Double.parseDouble(request.getParameter("confidence"));
            int support = Integer.parseInt(request.getParameter("support"));
            String word = request.getParameter("word");
            String sectype = request.getParameter("sectype");
            Long wordId =wordService.getWordIdByWordString(specialId, word);
            System.out.println(wordId);
            Long wordTypeId = wordService.getWordTypeByID(wordId);
            String sql;
            String countSql;


            sql = getSql(typeId, confidence, support, sectype, wordId, wordTypeId,specialId);
            countSql ="select count(*) from ("+sql+")temp";
            sql =sql+" limit " + pageNumber + "," + pageSize;

            List<Map> result = getBySqlMapper.findRecords(sql);
            if(result.size()<1){
                return null;
            }
            int total = getBySqlMapper.findrows(countSql);
            Map map = new HashMap();
            map.put("total", total);
            map.put("rows", result);
            map.put("page", pageNumber / pageSize);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }





    private String getSql(Integer typeId, double confidence, int support, String sectype, Long wordId, Long wordTypeId,Integer specialId) {

        String confidenceTable ="tb_confidence_copy";
        if (null!=specialId) {

            confidenceTable =confidenceTable+specialId;
        }
        String sql;
        if (typeId >wordTypeId) {
            sql = "SELECT (select word from tb_word where word_id =" + wordId + " ) as wordName, " +
                    "sum(b.num) as no,b.ano_word_id as wordId ,a.value as confidence, " +
                    "(select word from tb_word where word_id =wordId ) as name" +
                    " FROM  tb_words_relation_copy b left join "+confidenceTable+" a  on a.word_id=b.word_id " +
                    " and a.ano_word_id = b.ano_word_id " +
                    " and a.value>=" + confidence + "  and b.num >=" + support + " ";


            if (null != sectype && !sectype.isEmpty()) {
                sql = sql+ "AND b.sec_type ='" + sectype + "' ";
            }
            sql =sql+
                    " where a.word_id = " + wordId + " and b.ano_word_type ="+typeId +
                    " group by b.ano_word_id,a.value" +
                    " order by no desc ";

        } else {

            sql = "SELECT (select word from tb_word where word_id =" + wordId + " ) as wordName, " +
                    " sum(b.num) as no,b.word_id as wordId , a.value as confidence, " +
                    " (select word from tb_word where word_id =wordId ) as name" +
                    " FROM  tb_words_relation_copy b left join "+confidenceTable+" a " +
                    " on a.word_id=b.word_id and a.ano_word_id = b.ano_word_id" +
                    " and a.value>=" + confidence + "  and b.num >=" + support;



            if (null != sectype &&!sectype.isEmpty()) {
                sql = sql+" AND b.sec_type ='" + sectype + "' ";

            }

            sql =sql+
                    " where a.ano_word_id =  " + wordId + " and b.word_type ="+typeId +
                    " group by b.word_id,a.value" +
                    " order by no desc ";

        }
        return sql;
    }


}
